﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections.Generic;

namespace XorTool
{
    public partial class Form1 : Form
    {

        private IList<byte> content = null;
        private IList<byte> key = null;
        private IList<byte> result = null;

        public enum NumType
        {
            HEX = 1,
            DEC16,
            DEC32
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {

        }







        private void hexInput(object sender, KeyPressEventArgs e)
        {
            int i = 0;
            Console.WriteLine("..." + i++);
            if (Char.IsNumber(e.KeyChar) || (e.KeyChar >= 65 && e.KeyChar <= 70))
            {
                Console.WriteLine("...d" + i++);
                
            }
            else if (e.KeyChar >= 97 && e.KeyChar <= 102)
            {
                Console.WriteLine("...f" + i++);
                e.KeyChar -= (char)32;

            }
            else
            {
                e.Handled = true;
                Console.WriteLine("...g" + i++);
                this.TipContent.Text = "只能输入16进制数据";
                this.TipContent.Visible = true;
            }
        }



        private void hexInput(object sender, EventArgs e)
        {

            IList<byte> res;
            RichTextBox rtb = (RichTextBox)sender;
            if (rtb == null)
            {
                Console.WriteLine("当前输入框并非RichTextBox");
                return;
            }

            Label lbl = null;
            if (rtb.Name.Equals("InputContent"))
                lbl = this.TipContent;
            else if (rtb.Name.Equals("InputKey"))
                lbl = this.TipKey;


            int code = hexFormat(rtb.Text, out res);
            switch (code)
            {
                case 0:
                    {
                        lbl.Visible = false;
                    }
                    break;

                case 1:
                    {
                        lbl.Text = "只能输入16进制数据";
                        lbl.Visible = true;
                        res = null;
                    }
                    break;

                case 2:
                    {
                        lbl.Text = "包含4位的数";
                        lbl.Visible = true;
                        res = null;
                    }
                    break;
            }

            if (rtb.Name.Equals("InputContent"))
            {
                content = res;
            }
            else if (rtb.Name.Equals("InputKey"))
            {
                key = res;
            }

        }

        private void CalcBtnClick(object sender, EventArgs e)
        {
            if (Calc(content, key, out result))
            {
                // 将结果写入
/*                string res = "";
                foreach (var item in result)
                {
                    res = res + " " + item.ToString("x2");
                }
                this.OutputResult.Text = res;*/

                NumType nt = GetNumType();
                string res = FormatHexOrDec(nt, result);
                this.OutputResult.Text = res;

            }
            else
            {
                // 失败
                MessageBox.Show("计算失败，先解决错误提示");
            }
        }








        private NumType GetNumType()
        {
            if (this.RbResult16.Checked)
                return NumType.HEX;
            else if (this.RbResult10_16.Checked)
                return NumType.DEC16;
            else
                return NumType.DEC32;
        }


        private bool hexWordToData1(char key, out byte value)
        {
            value = 0;

            if (Char.IsNumber(key))
            {
                value = (byte)(key - 48);
                return true;
            }
            else if (key >= 65 && key <= 70)
            {
                value = (byte)(key - 55);
                return true;
            }
            else if (key >= 97 && key <= 102)
            {
                value = (byte)(key - 87);
                return true;
            }


            return false;
        }

        private bool hexWordToData2(char h, char l, out byte value)
        {
            value = 0;
            byte hh, ll;
            if (!hexWordToData1(h, out hh) || !hexWordToData1(l, out ll))
            {
                return false;
            }

            value = (byte)(hh << 4 | ll);
            return true;
        }


        // input    : 输入字符串
        // res      : 解析的结果
        // return   : 返回码       0-成功     1-包含非16进制字符串   2-包含4个字节的数据
        private int hexFormat(string input, out IList<byte> result)
        {
            result = new List<byte>();

            IList<char> temp = input.ToList<char>();

            // 分析
            List<char> cache = new List<char>();
            foreach (var item in temp)
            {
                if (item == 32)
                {
                    // 空格，不处理
                    continue;
                }

                cache.Add(item);
                if (cache.Count < 2)
                    continue;

                byte value;
                if (hexWordToData2(cache[0], cache[1], out value))
                {
                    cache.Clear();
                    result.Add(value);
                }
                else
                {
                    // 失败
                    return 1;
                }
            }

            if (cache.Count == 1)
            {
                return 2;
            }

            return 0;

        }


        private bool Calc(IList<byte> data, IList<byte> key, out IList<byte> res)
        {
            res = new List<byte>();
            if (data == null || data.Count < 1 || key == null || key.Count < 1)
            {
                return false;
            }


            int idxKey = 0;
            foreach (var item in data)
            {
                res.Add( (byte)(item ^ key[idxKey]));
                if (++idxKey >= key.Count)
                    idxKey = 0;
            }

            return true;

        }

        private string FormatHexOrDec( NumType type ,IList<byte> data)
        {
            if (data == null || data.Count < 1)
                return "";
            else
            {
                string res = "";
                switch (type)
                {
                    case NumType.HEX:
                        {
                            foreach (var item in data)
                            {
                                res = res + " " + item.ToString("x2");
                            }
                            
                        }
                        break;

                    case NumType.DEC16:
                        {
                            int tmp = 0;
                            for (int i = 1; i < data.Count; i += 2)
                            {
                                tmp = data[i - 1] << 8 | data[i];
                                res = res + " " + tmp.ToString("D5");
                            }
                            if (data.Count % 2 == 1)
                                res = res + " " + data[data.Count - 1].ToString("x2");

                        }
                        break;

                    case NumType.DEC32:
                        {
                            int tmp = 0;
                            for (int i = 3; i < data.Count; i += 4)
                            {
                                tmp = data[i - 3] << 24 | data[i - 2] << 16 | data[i - 1] << 8 | data[i];
                                res = res + " " + tmp.ToString("D11");
                            }

                            int n = data.Count % 4;
                            for (int i = 0; i < n; i++ )
                                res = res + " " + data[data.Count - n + i].ToString("x2");
                        }
                        break;
                }

                return res;
            }
        }

        private void RbResult16_CheckedChanged(object sender, EventArgs e)
        {
            if (result == null || result.Count < 1)
                return;

            string res = FormatHexOrDec(NumType.HEX, result);
            this.OutputResult.Text = res;
        }

        private void RbResult10_16_CheckedChanged(object sender, EventArgs e)
        {
            if (result == null || result.Count < 1)
                return;

            string res = FormatHexOrDec(NumType.DEC16, result);
            this.OutputResult.Text = res;
        }

        private void RbResult10_32_CheckedChanged(object sender, EventArgs e)
        {
            if (result == null || result.Count < 1)
                return;

            string res = FormatHexOrDec(NumType.DEC32, result);
            this.OutputResult.Text = res;
        }




    }
}
